package com.devo.icecream.ui.home

import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import com.devo.icecream.AppLogger
import com.devo.icecream.IceCreamApp
import com.devo.icecream.data.APIClient
import com.devo.icecream.data.Advertising
import com.devo.icecream.data.ProductBean
import com.devo.icecream.exception.APIException
import com.devo.icecream.receiver.WatchReceiver
import com.devo.icecream.socket.SocketClient
import com.devo.icecream.ui.BaseActivity
import com.devo.icecream.ui.advertising.AdvertActivity
import com.devo.icecream.ui.diy.DiyActivity
import com.devo.icecream.ui.order.OrderActivity
import com.devo.icecream.ui.theme.IcecreamTheme
import com.devo.icecream.utils.Time
import com.devo.icecream.utils.noRippleClickable
import com.devo.icecream.utils.toDateRange
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch


class HomeActivity : BaseActivity() {
    //产品  获取商品列表
    private val products = MutableStateFlow<List<ProductBean>>(arrayListOf())

    //机器状态
    private val status = MutableStateFlow<BusinessStatus>(BusinessStatus.OPEN)

    //打烊时间
    private val openRange = MutableStateFlow(Time.parse("0:0:0")..Time.parse("23:59:59"))
    private val adverts = MutableStateFlow<List<Advertising>>(listOf())

    private var countDownJob: Job? = null
    private var shutdownJob: Job? = null

    private var hideClickCount = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        WatchReceiver.isStop = false

        watchStatus()
        //重复提取产品
        repeatFetchProduct()
        //观察营业时间
        watchBusinessTime()
        //请求 type 为 2 的广告数据  获取制作中的广告
        requestAdverting()

        setContent {
            IcecreamTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    val foodList = products.collectAsState()
                    val state = status.collectAsState()
                    val ads = adverts.collectAsState()
                    Box(
                        modifier = Modifier
                            .fillMaxSize()
                            .noRippleClickable { resetCountDown() },
                    ) {
                        HomeScreen(
                            status = state.value,
                            products = foodList.value,
                            advertising = ads.value,
                            onDiyClick = {
                                startActivity(Intent(this@HomeActivity, DiyActivity::class.java))
                            },
                            onHideClick = {
                                hideClickCount += 1
                            },
                            onItemClick = {
                                startActivity(
                                    Intent(
                                        this@HomeActivity,
                                        OrderActivity::class.java
                                    ).apply {
                                        putExtra("goods", it)
                                    },
                                )
                            }
                        )
                    }
                }
            }
        }
    }


    /**
     * 请求 type 为 2 的广告数据
     */
    private fun requestAdverting() {
        lifecycleScope.launch {
            while (true) {
                try {
                    val ads = APIClient.getAdverts(2)
                    adverts.tryEmit(ads)
                    return@launch
                } catch (e: APIException) {
                    delay(5 * 1000)
                }
            }
        }
    }


    override fun onStart() {
        super.onStart()
        //设置倒计时
        resetCountDown()
    }


    private fun resetCountDown() {
        countDownJob?.cancel()
        countDownJob = lifecycleScope.launchWhenStarted {
            val deadline = 5 * 60 * 1000 + System.currentTimeMillis();
            //等待5分钟后跳转到广告页面
            while (deadline > System.currentTimeMillis()) {
                delay(1000)
            }
            startActivity(Intent(this@HomeActivity, AdvertActivity::class.java))
        }
    }

    private fun watchBusinessTime() {

        lifecycleScope.launch {
            var hideClickCache = 0
            while (true) {
                delay(1000)

                if (hideClickCount >= 10) {
                    WatchReceiver.isStop = true
                    delay(1000)
                    finish()
                } else {
                    hideClickCache = hideClickCount
                }

                if (System.currentTimeMillis() % 5000 == 0L && hideClickCache == hideClickCount) {
                    hideClickCount = 0
                }

                if (status.value == BusinessStatus.STOP) {
                    continue
                }

                status.tryEmit(
                    if (System.currentTimeMillis() in openRange.value.toDateRange()) {
                        BusinessStatus.OPEN
                    } else {
                        BusinessStatus.CLOSE(openRange.value)
                    }
                )

            }
        }
    }


    //重复提取产品
    private fun repeatFetchProduct() {
        lifecycleScope.launch {
            while (true) {
                if (status.value == BusinessStatus.OPEN) {
                    // PLC打开的话获取商品列表 获取产品
                    fetchProducts()
                }

                if (products.value.isNotEmpty()) {
                    delay(30 * 1000)
                } else {
                    delay(3 * 1000)
                }
            }
        }
    }

    //获取产品
    private suspend fun fetchProducts() {
        try {
            products.tryEmit(APIClient.getProducts(pageSize = 100))
        } catch (e: Exception) {
            AppLogger.e(e, "拉取商品报错")
        }
    }

    //观察
    private fun watchStatus() {
        //观察Socket返回的状态并更新状态
        watchUpdateStatus()
        //观察socket返回的营业时间并更新
        watchBusiness()
        //观察socket连接状态
        watchDisconnect()
        //观察著状态
        watchMaintainStatus()
    }

    //观察Socket返回的状态并更新状态
    private fun watchUpdateStatus() {
        lifecycleScope.launch {
            SocketClient.getUpdatedStatusFlow().collectLatest {
                AppLogger.w("后台更新状态：${it.status}");
                when (it.status) {
                    1 -> {
                        status.tryEmit(BusinessStatus.OPEN)
                    }
                    2 -> {
                        status.tryEmit(BusinessStatus.STOP)
                    }
                    else -> {
                        AppLogger.w("unknown status:${it.status}")
                    }
                }
            }
        }

    }

    //观察socket返回的营业时间并更新
    private fun watchBusiness() {
        lifecycleScope.launch {
            SocketClient.getBusinessTimeChangedFlow()
                .collectLatest { timeChanged ->
                    AppLogger.e(timeChanged.toString())
                    val timeRange = timeChanged.businessTimeDto.toRange()
                    openRange.tryEmit(timeRange)
                    if (System.currentTimeMillis() !in timeRange.toDateRange()) {
                        //开始延迟关机
                        IceCreamApp.get().startDelayShutdown()
                    }
                }
        }

    }

    //观察socket连接状态
    private fun watchDisconnect() {
        lifecycleScope.launch {
            SocketClient.getDisconnectFlow().collectLatest {
                status.tryEmit(BusinessStatus.STOP)
            }
        }

    }

    private fun watchMaintainStatus() {
        lifecycleScope.launch {
            while (true) {
                delay(1000)
                IceCreamApp.isNormal = status.value !is BusinessStatus.STOP
            }
        }
    }

}


sealed class BusinessStatus {
    object OPEN : BusinessStatus()
    object STOP : BusinessStatus()
    data class CLOSE(val range: ClosedRange<Time>) : BusinessStatus()
}